home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / gnu / emacs_src_18_58.lha / emacs-18.58 / src / amiga_tty.c < prev    next >
C/C++ Source or Header  |  1992-08-16  |  6KB  |  299 lines

  1. #include "config.h"
  2. #undef NULL
  3. #include "lisp.h"
  4. #include "termchar.h"
  5.  
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <internal/files.h>
  9. #include <internal/vars.h>
  10.  
  11. #undef LONGBITS
  12.  
  13. #include <exec/types.h>
  14. #include <dos/dos.h>
  15. #include <proto/exec.h>
  16.  
  17. #include "amiga.h"
  18. #include "termhooks.h"
  19.  
  20. static int term_initialised;
  21. ULONG inputsig;
  22.  
  23. /* A few tty system dependent routines unused on the Amiga */
  24.  
  25. setpgrp_of_tty(int pid) {}
  26. init_sigio() {}
  27. reset_sigio() {}
  28. request_sigio() {}
  29. unrequest_sigio() {}
  30.  
  31. /* Return nonzero if safe to use tabs in output.
  32.    At the time this is called, init_sys_modes has not been done yet.  */
  33.  
  34. tabs_safe_p()
  35. {
  36.   if (noninteractive)
  37.     return 1;
  38.  
  39.   return 0;            /* Not safe on Amiga !? */
  40. }
  41.  
  42. /* Get terminal size from system.
  43.    Store number of lines into *heightp and width into *widthp.
  44.    If zero or a negative number is stored, the value is not valid.  */
  45.  
  46. get_screen_size (widthp, heightp)
  47.      int *widthp, *heightp;
  48. {
  49.     if (term_initialised && !inhibit_window_system)
  50.     get_window_size(widthp, heightp);
  51.     else /* We don't known what size the terminal is */
  52.     {
  53.     *widthp = 0;
  54.     *heightp = 0;
  55.     }
  56. }
  57.  
  58. init_baud_rate ()
  59. {
  60.   if (noninteractive || !term_initialised) baud_rate = 1200;
  61.   else if (!inhibit_window_system) baud_rate = 38400;
  62.   else baud_rate = serial_baud_rate();
  63. }
  64.  
  65. void check_intuition ()
  66. {
  67.     if (noninteractive || inhibit_window_system)
  68.         error ("You aren't using a window.");
  69. }
  70.  
  71. #define TTYBUFSIZE 256        /* Same size as kbd_buffer */
  72. static char ttybuf[TTYBUFSIZE];
  73. static int tty_count;
  74. #define TTYPUT(c) { if (tty_count < TTYBUFSIZE) ttybuf[tty_count++] = c; }
  75.  
  76. static int interrupt_char;
  77.  
  78. void enque(unsigned int c, int meta)
  79. /* place input keys in keyboard buffer
  80.    If high bit is set, precede character with ^Q (hack).
  81.    If meta is true, set high bit.
  82.    If both the high bit & meta are true, we have a problem. Ignore it.
  83.    If c == AMIGASEQ (256) enqueue the amiga sequence introducer (C-x C-^)
  84. */
  85. {
  86.   /* Hack CSI to be AMIGASEQ (to allow defining function keys, etc) */
  87.   if (c == 0233 || c == AMIGASEQ)
  88.     {
  89.       TTYPUT('x' & 037); 
  90.       TTYPUT('^' & 037); 
  91.     }
  92.   else if (c >= 0200)    /* Special character, precede with ^Q */
  93.     {
  94.       TTYPUT('q' & 037);
  95.       TTYPUT(c);
  96.     }
  97.   else
  98.     {
  99.       if (meta) c |= 0200;
  100.       TTYPUT(c);
  101.       if (c == interrupt_char) Signal(_us, SIGBREAKF_CTRL_C);
  102.     }
  103. }
  104.  
  105. init_sys_modes ()
  106. {
  107.   extern int quit_char;
  108.  
  109.   if (noninteractive)
  110.     return;
  111.  
  112.   if (inhibit_window_system) clear_screen();
  113.  
  114.   interrupt_char = quit_char;
  115.   if (!inhibit_window_system) setup_intchar(interrupt_char);
  116. }
  117.  
  118. reset_sys_modes ()
  119. {
  120.   if (noninteractive)
  121.     {
  122.       fflush (stdout);
  123.       return;
  124.     }
  125.   move_cursor (screen_height - 1, 0);
  126.   clear_end_of_line (screen_width);
  127.   /* clear_end_of_line may move the cursor */
  128.   move_cursor (screen_height - 1, 0);
  129. }
  130.  
  131. void amiga_consume_input(void)
  132. {
  133.   extern int this_command_key_count;
  134.   int force = this_command_key_count == 0;
  135.   /* If force is TRUE & some non-keyboard (eg mouse events) input is pending,
  136.      insert the appropriate magic sequence in the input stream */
  137.  
  138.   if (term_initialised)
  139.     {
  140.       if (!inhibit_window_system) check_window(force);
  141.       else check_serial(force);
  142.       check_arexx(force, TRUE);
  143.     }
  144. }
  145.  
  146. discard_tty_input ()
  147. {
  148.   if (noninteractive)
  149.     return;
  150.  
  151.   amiga_consume_input();
  152.   tty_count = 0;
  153.   chkabort();
  154. }
  155.  
  156. /* Code for the fd describing the emacs input (terminal or window) */
  157.  
  158. static ULONG ttyin_select_start(void *userinfo, int rd, int wr)
  159. {
  160.   if (!inhibit_window_system) force_window();
  161.  
  162.   return tty_count ? -1 : inputsig;
  163. }
  164.  
  165. static void ttyin_select_poll(void *userinfo, int *rd, int *wr)
  166. {
  167.   amiga_consume_input();
  168.   if (!tty_count) *rd = 0;
  169. }
  170.  
  171. static int ttyin_read(void *userinfo, void *buffer, unsigned int length)
  172. {
  173.   amiga_consume_input();
  174.   if (length > tty_count) length = tty_count;
  175.   memcpy(buffer, ttybuf, length);
  176.   tty_count -= length;
  177.   if (tty_count) memmove(ttybuf, ttybuf + length, tty_count - length);
  178.  
  179.   return (int)length;
  180. }
  181.  
  182. static int ttyin_write(void *userinfo, void *buffer, unsigned int length)
  183. {
  184.   errno = EACCES;
  185.   return -1;
  186. }
  187.  
  188. static int ttyin_lseek(void *userinfo, long rpos, int mode)
  189. {
  190.   errno = ESPIPE;
  191.   return -1;
  192. }
  193.  
  194. static int ttyin_close(void *userinfo, int internal)
  195. {
  196.   return 0;
  197. }
  198.  
  199. static int ttyin_ioctl(void *userinfo, int request, void *data)
  200. {
  201.   errno = EINVAL;
  202.   return -1;
  203. }
  204.  
  205. #define CBUFSIZE 1024
  206. #undef fwrite
  207. #undef fflush
  208.  
  209. char cbuffer[CBUFSIZE + 16], *cbuffer_pos;
  210.  
  211. void emacs_fflush(FILE *f)
  212. {
  213.     if (noninteractive || f != stdout) _flsbf(-1, f);
  214.     else
  215.     {
  216.     int len;
  217.  
  218.     len = cbuffer_pos - cbuffer;
  219.     if (term_initialised)
  220.         if (!inhibit_window_system) screen_puts(cbuffer, len);
  221.         else serial_puts(cbuffer, len);
  222.     if (termscript) fwrite (cbuffer, 1, len, termscript);
  223.     cbuffer_pos = cbuffer;
  224.     }
  225. }
  226.  
  227. void emacs_putchar(int c)
  228. {
  229.     if (cbuffer_pos >= cbuffer + CBUFSIZE) emacs_fflush(stdout);
  230.     *cbuffer_pos++ = c;
  231. }
  232.  
  233. void emacs_output(char *str, int size)
  234. {
  235.     if (cbuffer_pos + size > cbuffer + CBUFSIZE) emacs_fflush(stdout);
  236.     if (size > CBUFSIZE)
  237.     {
  238.     if (term_initialised)
  239.         if (!inhibit_window_system) screen_puts(str, size);
  240.         else serial_puts(str, size);
  241.     }
  242.     else
  243.     {
  244.     memcpy(cbuffer_pos, str, size);
  245.     cbuffer_pos += size;
  246.     }
  247. }
  248.  
  249. void emacs_fwrite(char *str, unsigned int nblocks, unsigned int len, FILE *f)
  250. {
  251.     if (noninteractive || f != stdout) fwrite (str, nblocks, len, f);
  252.     else
  253.     {
  254.     unsigned int size;
  255.  
  256.     if (nblocks == 1) size = len; /* Emacs always uses 1 "block" */
  257.     else size = nblocks * len;
  258.  
  259.     emacs_output(str, size);
  260.     }
  261. }
  262.  
  263. void syms_of_amiga_tty(void)
  264. {
  265.   syms_of_amiga_screen();
  266.   syms_of_amiga_rexx();
  267. }
  268.  
  269. void init_amiga_tty()
  270. {
  271.   inputsig = 0;
  272.   term_initialised = FALSE;
  273.   init_amiga_rexx();
  274. }
  275.  
  276. void cleanup_amiga_tty()
  277. {
  278.   cleanup_amiga_rexx();
  279.   cleanup_amiga_serial();
  280.   cleanup_amiga_screen();
  281. }
  282.  
  283. void early_amiga_tty()
  284. {
  285.   cbuffer_pos = cbuffer;
  286.   tty_count = 0;
  287. }
  288.  
  289. void amiga_term_open(void)
  290. {
  291.   inhibit_window_system ? init_amiga_serial() : init_amiga_screen();
  292.   close(0);
  293.   if (_alloc_fd((void *)1, FI_READ, ttyin_select_start, ttyin_select_poll, ttyin_read,
  294.         ttyin_write, ttyin_lseek, ttyin_close, ttyin_ioctl) == 0)
  295.     term_initialised = TRUE;
  296.   else _fail("Failed to initialise I/O, no memory ?");
  297. }
  298.  
  299.